package com.rdgzs.framework.utilsTools;

import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import javax.servlet.http.HttpServletResponse;

import net.sf.json.JSON;
import net.sf.json.JSONObject;
import net.sf.json.JSONSerializer;
import net.sf.json.JsonConfig;
import net.sf.json.util.CycleDetectionStrategy;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springside.modules.orm.Page;

import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonParser;
import com.rdgzs.framework.constant.SysConstants;

public class UtilsObject {
	private static final Log logger = LogFactory.getLog(UtilsObject.class);
	private static final String SPECS[][] = { { "\"", "&quot;" }, { "<", "&lt;" }, { ">", "&gt;" }, { "‘", "&lsquo;" }, { "’", "&rsquo;" },
			{ "“", "&ldquo;" }, { "”", "&rdquo;" }, { "(", "&#40;" }, { ")", "&#41;" }, { ",", "&#44;" }, { "=", "&#61;" },
			{ "*", "&#42;" }, { "'", "&#39;" }, { "\\", "&#92;" }, { "^", "&#94;" }, { " ", "&nbsp;" }, { "--", "&oline;&oline;" } };

	/**
	 * 32位的uuid
	 * 
	 * @return
	 */
	public static String getUuidStr() {
		String uuid = UUID.randomUUID().toString().replace("-", "");
		return uuid;
	}

	/**
	 * 以指定的格式回写ajax信息
	 * 
	 * @param response
	 * @param jsonStr
	 * @return
	 * @throws Exception
	 */
	public static void writeAjaxInfo(HttpServletResponse response, String jsonStr, String contentType) throws Exception {
		// 设置字符集
		response.setContentType(contentType);
		response.setCharacterEncoding(SysConstants.ENCODING_UTF8);
		response.setHeader("Cache-Control", "no-cache"); // 清除缓存
		PrintWriter out = response.getWriter();
		// 直接输入响应的内容
		out.write(jsonStr);
		out.flush();
		out.close();
	}

	/**
	 * 以Json的格式回写ajax信息
	 * 
	 * @param response
	 * @param jsonStr
	 * @return
	 * @throws Exception
	 */
	public static void WriteAjaxInfoJson(HttpServletResponse response, String jsonStr) throws Exception {
		writeAjaxInfo(response, jsonStr, SysConstants.CONTENTTYPE_JSON);
	}

	/**
	 * 以文本格式回写ajax信息
	 * 
	 * @param response
	 * @param jsonStr
	 * @return
	 * @throws Exception
	 */
	public static void WriteAjaxInfoText(HttpServletResponse response, String jsonStr) throws Exception {
		writeAjaxInfo(response, jsonStr, SysConstants.CONTENTTYPE_TEXT);
	}

	/**
	 * 导出Excel文件
	 * 
	 * @param response
	 * @param fileName
	 * @throws Exception
	 */
	public static void WriteExcel(HttpServletResponse response, String fileName) throws Exception {
		response.setContentType("application/vnd.ms-excel");
		response.setCharacterEncoding(SysConstants.ENCODING_UTF8);
		if (fileName != null && fileName.length() > 0) {
			fileName = new String(fileName.getBytes(SysConstants.ENCODING_UTF8), SysConstants.ENCODING_ISO8859);
			response.setHeader("Content-Disposition", "attachment;filename=" + fileName);
		}
		response.flushBuffer();
	}

	/**
	 * 将date格式化为默认的日期格式
	 * 
	 * @param response
	 * @param jsonStr
	 * @return
	 * @throws Exception
	 */
	public static Date DateDefautlForamt(Date date) throws Exception {
		try {
			String dateStr = DateTimeUtils.dateToStr(date, DateTimeUtils.SDF_YYYY_MM_DD);
			return DateTimeUtils.strToDate(dateStr, DateTimeUtils.SDF_YYYY_MM_DD);
		} catch (Exception e) {
			e.printStackTrace();
			throw e;
		}
	}

	/**
	 * 将字符串转为date ,按默认YYYY-MM-DD
	 * 
	 * @param dateStr
	 * @return
	 * @throws Exception
	 */
	public static Date str2date(String dateStr) throws Exception {
		try {
			return DateTimeUtils.strToDateDefault(dateStr);
		} catch (Exception e) {
			e.printStackTrace();
			throw e;
		}
	}

	/**
	 * 根据page得到order by 语句
	 * 
	 * @return
	 */
	public static String getOrderBySql(Page page) {
		String orderBySql = "";
		if (page != null) {
			if (StringUtils.isNotBlank(page.getOrderBy())) {
				orderBySql += " order by " + page.getOrderBy() + " ";
				if (StringUtils.isNotBlank(page.getOrder())) {
					orderBySql += " " + page.getOrder() + " ";
				} else {
					orderBySql += " " + Page.ASC + " ";
				}
			}
		}
		return orderBySql;
	}

	/**
	 * 设置JsonConfig 排除hibernate的懒加载对像和指定对像
	 * 
	 * @param arr
	 * @return
	 */
	public static JsonConfig Obj2JsonConfig_excludes(String[] arr) {
		List<String> excOjbs = new ArrayList<String>();
		excOjbs.add("handler");
		excOjbs.add("hibernateLazyInitializer");
		for (String objName : arr) {
			excOjbs.add(objName);
		}
		String[] array = excOjbs.toArray(arr);
		JsonConfig config = new JsonConfig();
		config.setIgnoreDefaultExcludes(false);
		config.setCycleDetectionStrategy(CycleDetectionStrategy.LENIENT);
		config.setExcludes(array);
		config.registerJsonValueProcessor(java.sql.Timestamp.class, new JsonDateFormat("yyyy-MM-dd"));
		config.registerJsonValueProcessor(java.util.Date.class, new JsonDateFormat("yyyy-MM-dd"));
		return config;
	}

	/**
	 * 设置JsonConfig 排除hibernate的懒加载对像
	 * 
	 * @return
	 */
	public static JsonConfig Obj2JsonConfig_excludes() {
		JsonConfig config = new JsonConfig();
		config.registerJsonValueProcessor(java.sql.Timestamp.class, new JsonDateFormat("yyyy-MM-dd"));
		config.registerJsonValueProcessor(java.util.Date.class, new JsonDateFormat("yyyy-MM-dd"));
		config.setIgnoreDefaultExcludes(false);
		config.setCycleDetectionStrategy(CycleDetectionStrategy.LENIENT);
		config.setExcludes(new String[] { "handler", "hibernateLazyInitializer" });
		return config;
	}

	/**
	 * 将对像转为JsonElement不转换hibernate的懒加载对像和指定的元素对像
	 * 
	 * @param obj
	 * @param arr
	 * @return
	 */
	public static JsonElement Obj2Gson(Object obj, String[] arr) {
		JsonParser jsonParser = new JsonParser();
		String jsonStr = JSONSerializer.toJSON(obj, Obj2JsonConfig_excludes(arr)).toString();
		return jsonParser.parse(jsonStr);
	}

	/**
	 * 将对像转为JsonElement 不转换hibernate 的懒加载
	 * 
	 * @param obj
	 * @return
	 */
	public static JsonElement Obj2GsonExc(Object obj) {
		JsonParser jsonParser = new JsonParser();
		String jsonStr = JSONSerializer.toJSON(obj, Obj2JsonConfig_excludes()).toString();
		return jsonParser.parse(jsonStr);
	}

	/**
	 * Gson提供的类型转换
	 * 
	 * @param obj
	 * @return
	 */
	public static JsonElement Obj2Gson(Object obj) {
		Gson gson = new Gson();
		JsonParser jsonParser = new JsonParser();
		String jsonStr = gson.toJson(obj);
		return jsonParser.parse(jsonStr);
	}

	/**
	 * 字符串转为Json
	 * 
	 * @param obj
	 * @return
	 */
	public static JsonElement str2Json(String jsonStr) {
		JsonParser jsonParser = new JsonParser();
		return jsonParser.parse(jsonStr);
	}

	/**
	 * 字符串转为Json数组
	 * 
	 * @param obj
	 * @return
	 */
	public static JsonArray str2JsonArray(String jsonStr) {
		return str2Json(jsonStr).getAsJsonArray();
	}

	/**
	 * 将Json串转为Map对像
	 * 
	 * @param obj
	 * @return
	 */
	public static Map parserToMap(String s) {
		Map map = new HashMap();
		JSONObject json = JSONObject.fromObject(s);
		Iterator keys = json.keys();
		while (keys.hasNext()) {
			String key = (String) keys.next();
			String value = json.get(key).toString();
			if (value.startsWith("{") && value.endsWith("}")) {
				map.put(key, parserToMap(value));
			} else {
				map.put(key, value);
			}
		}
		return map;
	}

	// <<<<<<<<<<<<<<<<<<<<<<<< 数组操作 >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
	/**
	 * 将字符串转为数组
	 * 
	 * @param ArrayStr
	 * @param separator
	 * @return
	 */
	public static String[] str2Array(String ArrayStr, String separator) {
		if (ArrayStr == null) {
			return null;
		}
		if (StringUtils.isBlank(separator)) {
			return new String[] { ArrayStr };
		}
		String[] StrArray = ArrayStr.split(separator);
		return StrArray;
	}

	/**
	 * 将默认格式字符串 转为 数组
	 * 
	 * @param ArrayStr
	 * @param separator
	 * @return
	 */
	public static String[] str2Array_comma(String ArrayStr) {
		return str2Array(ArrayStr, SysConstants.SEPARATOR_COMMA);
	}

	/**
	 * 将数组转为字符串
	 * 
	 * @param ArrayStr
	 * @return
	 */
	public static String Array2str(String[] ArrayStr, String separator) {
		StringBuffer arrStr = new StringBuffer("");
		for (String str : ArrayStr) {
			arrStr.append(str);
			arrStr.append(separator);
		}
		if (arrStr.toString().length() > 0) {
			return arrStr.toString().substring(0, arrStr.toString().length() - 1);
		}
		return arrStr.toString();
	}

	/**
	 * 将数组转为默认格式的字符串
	 * 
	 * @param ArrayStr
	 * @return
	 */
	public static String Array2str_comma(String[] ArrayStr) {
		return Array2str(ArrayStr, SysConstants.SEPARATOR_COMMA);
	}

	/**
	 * 数组转为list
	 * 
	 * @param ArrayStr
	 * @return
	 */
	public static List Array2List(String[] ArrayStr) {
		List arrList = new ArrayList();
		for (String str : ArrayStr) {
			arrList.add(str);
		}
		return arrList;
	}

	/**
	 * 字符串转为list
	 * 
	 * @param ArrayStr
	 * @return
	 */
	public static List<String> str2List(String ArrayStr) {
		if (StringUtils.isNotBlank(ArrayStr)) {
			List arrList = new ArrayList();
			for (String str : str2Array_comma(ArrayStr)) {
				arrList.add(str);
			}
			return arrList;
		} else {
			return new ArrayList();
		}
	}

	//
	// /**
	// * 获取页面自动补全的的代码表信息
	// *
	// * @param typeCode
	// * 代码表类型
	// * @param q
	// * 页面自动补全输入框的值
	// * @return
	// * @throws Exception
	// */
	// public static List getDataListForAutoComplete(String typeCode, String q) throws Exception {
	// List retList = new ArrayList();
	// try {
	// List<DictData> inquiryTypeList = DictionaryUtils.get(typeCode);
	// for (DictData dictData : inquiryTypeList) {
	// String parameterCode = dictData.getParameterCode();
	// String parameterName = dictData.getParameterName();
	// String[] parameterPinyins = Pinyin4jUtil.makeStringByStringSet(Pinyin4jUtil.getPinyin(parameterName))
	// .split(SysConstants.SEPARATOR_COMMA);
	//
	// for (String parameterPinyin : parameterPinyins) {
	// if (parameterName.startsWith(q) || parameterPinyin.startsWith(q)) {
	// DictDataVO dictDataVO = new DictDataVO();
	// dictDataVO.setTypeCode(typeCode);
	// dictDataVO.setParameterCode(parameterCode);
	// dictDataVO.setParameterName(parameterName);
	// if (!retList.contains(dictDataVO)) {
	// retList.add(dictDataVO);
	// }
	// }
	// }
	// }
	// } catch (Exception e) {
	// e.printStackTrace();
	// throw e;
	// }
	// return retList;
	// }
	/**
	 * @param 创建日期：2012－12－21 
	 * @param 开发人员：李广彬 
	 * @param 功能描述：将user转为setUser 
	 * @param 传入参数：变量名
	 * @see
	 * @category
	 * @author ligb
	 */
	public static String varName2getterName(final String varName) {
		return "get" + varName.substring(0, 1).toUpperCase() + varName.substring(1);
	}

	/**
	 * @创建日期：2012－12－21
	 * @开发人员：李广彬
	 * @功能描述：将user转为setUser
	 * @传入参数：变量名
	 */
	public static String varName2setterName(final String varName) {
		return "set" + varName.substring(0, 1).toUpperCase() + varName.substring(1);
	}

	/**
	 * @创建日期：2012－12－21
	 * @开发人员：李广彬
	 * @功能描述：将对像里的空对像设置为指定的内容
	 * @传入参数：带前缀的方式
	 */
	public static Map objVarBlank2param(Object obj, Object newVal) throws IllegalArgumentException, IllegalAccessException,
			InvocationTargetException {
		Map resultMap = new HashMap();
		Method[] methods = obj.getClass().getMethods();
		String varName = null;
		String methodName = null;
		Object value = null;
		for (Method method : methods) {
			try {
				methodName = method.getName();
				if (methodName.substring(0, 3).equals("get")) {
					varName = UtilsObject.MethodName2varName_GS(methodName);
					value = method.invoke(obj);
					if (value instanceof java.lang.String) {
						String val = (String) value;
						if (val == null || val.trim().length() == 0) {
							String setname = varName2setterName(varName);
							Method setter = obj.getClass().getMethod(setname, java.lang.String.class);
							setter.invoke(obj, newVal);
						}
					}
				}
			} catch (Exception e) {
				logError(logger, e);
			}
		}
		return resultMap;
	}

	/**
	 * 创建日期：2012－12－21 开发人员：李广彬 功能描述：List对像转为以指定属性为Key的Map 传入参数：带前缀的方式
	 */
	public static Map list2map(List<Object> objs, String propertyName) throws SecurityException, NoSuchMethodException,
			IllegalArgumentException, IllegalAccessException, InvocationTargetException {
		Map resultMap = new HashMap();
		Object key = null;
		for (Object obj : objs) {
			Method method = obj.getClass().getMethod(varName2getterName(propertyName), null);
			key = method.invoke(obj);
			resultMap.put(key, obj);
		}
		return resultMap;
	}

	/**
	 * 创建日期：2012－12－21 开发人员：李广彬 功能描述：List对像转为以指定属性为Key的Map 传入参数：带前缀的方式
	 */
	public static List list2propertyList(List objs, String propertyName) throws SecurityException, NoSuchMethodException,
			IllegalArgumentException, IllegalAccessException, InvocationTargetException {
		List resultList = new ArrayList();
		Object val = null;
		for (Object obj : objs) {
			Method method = obj.getClass().getMethod(varName2getterName(propertyName), null);
			val = method.invoke(obj);
			resultList.add(val);
		}
		return resultList;
	}

	// 将list对像放到Map里
	public static Map list2Map(List objs) throws Exception {
		Map objsMap = new HashMap();
		for (Object obj : objs) {
			Method objMethod = obj.getClass().getMethod("getId", new Class[] {});
			String objId = (String) objMethod.invoke(obj, new Class[] {});
			objsMap.put(objId, obj);
		}
		return objsMap;
	}

	// 将list对像放到Map里
	public static Map list2Map(List objs, String methodStr) throws Exception {
		Map objsMap = new HashMap();
		for (Object obj : objs) {
			Method objMethod = obj.getClass().getMethod(methodStr, new Class[] {});
			String objId = (String) objMethod.invoke(obj, new Class[] {});
			objsMap.put(objId, obj);
		}
		return objsMap;
	}

	// 进行MD5加密
	public static String md5(String str) throws NoSuchAlgorithmException {
		MessageDigest md5 = MessageDigest.getInstance("MD5");
		StringBuffer strbuf = new StringBuffer();
		md5.update(str.getBytes(), 0, str.length());
		byte[] digest = md5.digest();
		for (int i = 0; i < digest.length; i++) {
			strbuf.append(byte2Hex(digest[i]));
		}
		return strbuf.toString();
	}

	private static String byte2Hex(byte b) {// 0x7F:-1 0x80等于十进制的128
		int value = (b & 0x7F) + (b < 0 ? 0x80 : 0);
		return (value < 0x10 ? "0" : "") + Integer.toHexString(value).toLowerCase();
	}

	// /**
	// * 自动取得数据字典
	// *
	// * @param dictTypeCode
	// * @throws Exception
	// */
	// public static String getDictList(String dictTypeCode) throws Exception {
	// List<DictData> list = DictionaryUtils.get(dictTypeCode);
	// String[] field_excludes = new String[6];
	// field_excludes[0] = "optimistic";
	// field_excludes[1] = "createTime";
	// field_excludes[2] = "modifyTime";
	// field_excludes[3] = "createId";
	// field_excludes[4] = "modifyId";
	// field_excludes[5] = "dictType";
	// JsonConfig jsonConfig_excludes = UtilsObject.Obj2JsonConfig_excludes(field_excludes);
	// JSONArray qualificationFields = JSONArray.fromObject(list, jsonConfig_excludes);
	// return qualificationFields.toString();
	// }
	/**
	 * 字符串编码转换的实现方法
	 * 
	 * @param str 待转换编码的字符串
	 * @param newCharset 目标编码
	 * @return
	 * @throws UnsupportedEncodingException
	 */
	public static String changeCharset(String str, String newCharset) throws UnsupportedEncodingException {
		if (str != null) {
			// 用默认字符编码解码字符串。
			byte[] bs = str.getBytes();
			// 用新的字符编码生成字符串
			return new String(bs, newCharset);
		}
		return null;
	}

	/**
	 * 将exception 转为 字符串流
	 * 
	 * @param e
	 * @return
	 */
	public static String exception2string(Exception e) {
		String exceptionStack = null;
		if (e != null) {
			StringWriter sw = new StringWriter();
			PrintWriter pw = new PrintWriter(sw);
			try {
				e.printStackTrace(pw);
				exceptionStack = sw.toString();
			} finally {
				try {
					sw.close();
					pw.close();
				} catch (IOException ioe) {
					exceptionStack = ioe.getMessage();
				}
			}
		}
		return exceptionStack;
	}

	/**
	 * 将异常输出到指定的Log系统中
	 * 
	 * @param log
	 * @param e
	 */
	public static void logError(Log log, Exception e) {
		log.error(exception2string(e));
	}

	/**
	 * 将异常输出到指定的Log系统中
	 * 
	 * @param log
	 * @param e
	 */
	public static void logDebug(Log log, Exception e) {
		log.debug(exception2string(e));
	}

	/**
	 * 将异常输出为指定的错误类型
	 * 
	 * @param log
	 * @param e
	 * @param level
	 */
	public static void log(Log log, Exception e, char level) {
		switch (level) {
		case 'e':
			log.error(exception2string(e));
			break;
		case 'w':
			log.warn(exception2string(e));
			break;
		case 'd':
			log.debug(exception2string(e));
			break;
		case 'i':
			log.info(exception2string(e));
			break;
		case 't':
			log.trace(exception2string(e));
			break;
		case 'f':
			log.fatal(exception2string(e));
			break;
		}
	}

	/**
	 * 对字符串进行url编码转换 默认UTF－8编码
	 * 
	 * @param str
	 * @return
	 * @throws UnsupportedEncodingException
	 */
	public static String encode(String str) throws UnsupportedEncodingException {
		return URLEncoder.encode(str, SysConstants.ENCODING_UTF8);
	}

	/**
	 * 对URL编码字符串进行转换 默认UTF－8编码
	 * 
	 * @param str
	 * @return
	 * @throws UnsupportedEncodingException
	 */
	public static String decode(String str) throws UnsupportedEncodingException {
		return URLDecoder.decode(str, SysConstants.ENCODING_UTF8);
	}

	/**
	 * 创建日期：2012－12－21 开发人员：李广彬 功能描述：将setUser转为user 传入参数：get set 方法名转变量名
	 */
	public static String MethodName2varName_GS(final String setterName) {
		String varName = setterName.substring(3);
		varName = varName.substring(0, 1).toLowerCase() + varName.substring(1);
		return varName;
	}

	/**
	 * 创建日期：2012－12－21 开发人员：李广彬 功能描述：将对像转为key-value对 传入参数：
	 */
	public static Map obj2map(Object obj) throws Exception {
		return UtilsObject.obj2map(obj, "");
	}

	/**
	 * 创建日期：2012－12－21 开发人员：李广彬 功能描述：将对像转为key-value对 传入参数：带前缀的方式
	 */
	public static Map obj2map(Object obj, String prefix) {
		Map resultMap = new HashMap();
		Method[] methods = obj.getClass().getMethods();
		String varName = null;
		String methodName = null;
		Object value = null;
		for (Method method : methods) {
			try {
				methodName = method.getName();
				if (methodName.substring(0, 3).equals("get")) {
					varName = UtilsObject.MethodName2varName_GS(methodName);
					value = method.invoke(obj);
					if (value != null) {
						resultMap.put(prefix + varName, value);
					}
				}
			} catch (IllegalAccessException e) {
				logDebug(logger, e);
			} catch (IllegalArgumentException e) {
				logDebug(logger, e);
			} catch (InvocationTargetException e) {
				logDebug(logger, e);
			} catch (Exception e) {
				logError(logger, e);
			}
		}
		return resultMap;
	}

	/**
	 * 将html字符串转换为html编码方法
	 * 
	 * @param str
	 * @return
	 */
	private String convertHTML(String str) {
		if (str != null) {
			int size = SPECS.length;
			int i = 0;
			while (i < size) {
				str = str.replace(SPECS[i][0], SPECS[i][1]);
				i++;
			}
		}
		return str;
	}

	public static void main(String args[]) throws NoSuchAlgorithmException {
		System.out.println(UUID.randomUUID().version() + "md5:" + md5("123456"));
	}
}
